/**
 * @file pod_characteristics_test.cpp
 * @brief POD特性测试程序
 * 
 * 测试不同构造函数和赋值函数对POD性质的影响
 */

#include <iostream>
#include <type_traits>
#include <string>
#include <vector>

// 测试各种结构体的POD特性
namespace pod_test {

// 1. 最严格的POD (C-style)
struct StrictPOD {
    int x;
    float y;
    char z[10];
};

// 2. 带默认值的结构体
struct WithDefaults {
    int x = 0;
    float y = 1.0f;
    bool flag = false;
};

// 3. 带默认构造函数的结构体
struct WithDefaultConstructor {
    int x;
    float y;
    
    WithDefaultConstructor() = default;  // 显式默认构造函数
};

// 4. 带用户定义构造函数的结构体
struct WithUserConstructor {
    int x;
    float y;
    
    WithUserConstructor(int x_, float y_) : x(x_), y(y_) {}
};

// 5. 带默认拷贝操作的结构体
struct WithDefaultCopy {
    int x = 0;
    float y = 0.0f;
    
    WithDefaultCopy() = default;
    WithDefaultCopy(const WithDefaultCopy&) = default;
    WithDefaultCopy& operator=(const WithDefaultCopy&) = default;
    WithDefaultCopy(WithDefaultCopy&&) = default;
    WithDefaultCopy& operator=(WithDefaultCopy&&) = default;
};

// 6. 带用户定义拷贝操作的结构体
struct WithUserCopy {
    int x = 0;
    float y = 0.0f;
    
    WithUserCopy() = default;
    WithUserCopy(const WithUserCopy& other) : x(other.x), y(other.y) {}
    WithUserCopy& operator=(const WithUserCopy& other) {
        if (this != &other) {
            x = other.x;
            y = other.y;
        }
        return *this;
    }
};

// 7. 带非POD成员的结构体
struct WithNonPODMembers {
    int x = 0;
    std::string name;  // 非POD成员
    std::vector<int> data;  // 非POD成员
    
    WithNonPODMembers() = default;
    WithNonPODMembers(const WithNonPODMembers&) = default;
    WithNonPODMembers& operator=(const WithNonPODMembers&) = default;
    WithNonPODMembers(WithNonPODMembers&&) = default;
    WithNonPODMembers& operator=(WithNonPODMembers&&) = default;
};

// 8. 带虚函数的结构体
struct WithVirtual {
    int x = 0;
    float y = 0.0f;
    
    WithVirtual() = default;
    virtual ~WithVirtual() = default;
    virtual void foo() {}
};

// 9. 我们生成的结构体风格
struct GeneratedStyle {
    uint64_t id = 0;
    std::string name;
    std::vector<int> scores;
    bool flag = false;
    
    // 默认构造函数
    GeneratedStyle() = default;
    
    // 拷贝构造和赋值
    GeneratedStyle(const GeneratedStyle&) = default;
    GeneratedStyle& operator=(const GeneratedStyle&) = default;
    GeneratedStyle(GeneratedStyle&&) = default;
    GeneratedStyle& operator=(GeneratedStyle&&) = default;
    
    // 比较操作符
    bool operator==(const GeneratedStyle& other) const {
        return id == other.id && 
               name == other.name && 
               scores == other.scores && 
               flag == other.flag;
    }
    
    bool operator!=(const GeneratedStyle& other) const {
        return !(*this == other);
    }
};

/**
 * @brief 打印类型特性
 */
template<typename T>
void print_type_traits(const std::string& type_name) {
    std::cout << "\n=== " << type_name << " ===\n";
    
    // C++11及以后的类型特性
    std::cout << "is_trivial: " << std::is_trivial<T>::value << "\n";
    std::cout << "is_trivially_copyable: " << std::is_trivially_copyable<T>::value << "\n";
    std::cout << "is_standard_layout: " << std::is_standard_layout<T>::value << "\n";
    
    // C++11中，POD = trivial + standard_layout
    bool is_pod_cpp11 = std::is_trivial<T>::value && std::is_standard_layout<T>::value;
    std::cout << "is_pod (C++11定义): " << is_pod_cpp11 << "\n";
    
#if __cplusplus >= 201103L
    // C++14及以后有专门的is_pod
    #ifdef __cpp_lib_is_pod
    std::cout << "std::is_pod: " << std::is_pod<T>::value << "\n";
    #endif
#endif
    
    // 其他有用的特性
    std::cout << "is_trivially_constructible: " << std::is_trivially_constructible<T>::value << "\n";
    std::cout << "is_trivially_destructible: " << std::is_trivially_destructible<T>::value << "\n";
    std::cout << "is_trivially_copy_constructible: " << std::is_trivially_copy_constructible<T>::value << "\n";
    std::cout << "is_trivially_copy_assignable: " << std::is_trivially_copy_assignable<T>::value << "\n";
    std::cout << "is_trivially_move_constructible: " << std::is_trivially_move_constructible<T>::value << "\n";
    std::cout << "is_trivially_move_assignable: " << std::is_trivially_move_assignable<T>::value << "\n";
    
    // 内存相关
    std::cout << "sizeof: " << sizeof(T) << " bytes\n";
    std::cout << "alignof: " << alignof(T) << " bytes\n";
}

} // namespace pod_test

int main() {
    std::cout << "POD特性测试程序\n";
    std::cout << "=================================\n";
    std::cout << "测试不同构造函数和赋值函数对POD性质的影响\n";
    
    // 测试各种结构体
    pod_test::print_type_traits<pod_test::StrictPOD>("StrictPOD (C-style)");
    pod_test::print_type_traits<pod_test::WithDefaults>("WithDefaults (带默认值)");
    pod_test::print_type_traits<pod_test::WithDefaultConstructor>("WithDefaultConstructor (= default)");
    pod_test::print_type_traits<pod_test::WithUserConstructor>("WithUserConstructor (用户定义)");
    pod_test::print_type_traits<pod_test::WithDefaultCopy>("WithDefaultCopy (= default拷贝)");
    pod_test::print_type_traits<pod_test::WithUserCopy>("WithUserCopy (用户定义拷贝)");
    pod_test::print_type_traits<pod_test::WithNonPODMembers>("WithNonPODMembers (string/vector成员)");
    pod_test::print_type_traits<pod_test::WithVirtual>("WithVirtual (虚函数)");
    pod_test::print_type_traits<pod_test::GeneratedStyle>("GeneratedStyle (我们生成的风格)");
    
    std::cout << "\n=== 总结 ===\n";
    std::cout << "1. = default的构造/赋值函数不影响trivial性质\n";
    std::cout << "2. 用户定义的构造/赋值函数会破坏trivial性质\n";
    std::cout << "3. 非POD成员(如string/vector)会破坏trivial性质\n";
    std::cout << "4. 虚函数会破坏POD性质\n";
    std::cout << "5. 我们生成的结构体虽然不是严格POD，但保持了很多有用特性\n";
    
    std::cout << "\n=== 实际影响 ===\n";
    std::cout << "- trivially_copyable: 可以用memcpy安全拷贝\n";
    std::cout << "- standard_layout: 内存布局可预测，与C兼容\n";
    std::cout << "- trivial: 可以用简单的位操作\n";
    std::cout << "- 即使不是严格POD，现代编译器仍能很好优化\n";
    
    return 0;
}
